package opgave2;

public class Verzameling<E extends Data> implements VerzamelingInterface<E> {
	private Lijst<E> data;

	public Verzameling() {
		data = new Lijst<E>();
	}
	
	public void init() {
		data.init();
	}

	public void add(E d) {
		// Lijst zorgt al dat er een kopie van d wordt toegevoegd, dus niet overbodig klonen hier.
		if(!data.find(d)) {
			data.insert(d);
		}
	}

	public E take() {
		data.setFirst();
		E result = data.retrieve();
		data.remove();
		return result;
	}
	
	public boolean isEmpty() {
		return size() == 0;
	}

	public int size() {
		return data.size();
	}

	public boolean contains(E d) {
		return data.find(d);
	}

	public Verzameling<E> verschil(Verzameling<E> verz2) {
		// Maakt een verzameling aan
		Verzameling<E> resultaat = new Verzameling<E>();
		// Maakt kopie van de verzameling 1 aan, waarvan de take gebruikt word.
		Verzameling<E> kopie = clone();
		
		// Gaat voor elk element in deze verzameling kijken of deze in verzameling 2 zit
		for (int i = kopie.size() - 1; i >= 0; i--) {
			E d = kopie.take();
			if(!verz2.contains(d)) {
				resultaat.add(d);
			}
		}
		
		return resultaat;
	}

	public Verzameling<E> doorsnede(Verzameling<E> verz2) {
		// Maak een verzameling aan
		Verzameling<E> resultaat = new Verzameling<E>();
		// Maakt kopie van de verzameling 1 aan, waarvan de take gebruikt word.
		Verzameling<E> kopie = clone();
		
		// Gaat voor elk element in deze verzameling of deze ook in verzameling 2 zit
		for (int i = kopie.size() - 1; i >= 0; i--) {
			E d = kopie.take();
			if(verz2.contains(d)) {
				resultaat.add(d);
			}
		}
		
		return resultaat;
	}

	public Verzameling<E> vereniging(Verzameling<E> verz2) {
		// Maak een verzameling aan
		Verzameling<E> resultaat = new Verzameling<E>();

		// Maakt kopieen van de verzamelingen aan, waarvan de take gebruikt word.
		Verzameling<E> kopie = clone();
		Verzameling<E> verz2kopie = verz2.clone();
		
		for (int i = kopie.size() - 1; i >= 0; i--) {
			E d = kopie.take();
			resultaat.add(d);
		}
		
		for (int i = verz2kopie.size() - 1; i >= 0; i--) {
			E d = verz2kopie.take();
			if(!resultaat.contains(d)) {
				resultaat.add(d);
			}
		}
		
		return resultaat;
	}

	public Verzameling<E> symvers(Verzameling<E> verz2) {
		// Maak een verzameling aan
		Verzameling<E> resultaat = new Verzameling<E>();
		
		// Maakt kopieen van de verzamelingen aan, waarvan de take gebruikt word.
		Verzameling<E> kopie = clone();
		Verzameling<E> verz2kopie = verz2.clone();
		
		for (int i = kopie.size() - 1; i >= 0; i--) {
			E d = kopie.take();
			if(!verz2kopie.contains(d)) {
				resultaat.add(d);
			}
		}
		
		for (int i = verz2kopie.size() - 1; i >= 0; i--) {
			E d = verz2kopie.take();
			if(!contains(d)) {
				resultaat.add(d);
			}
		}
		
		return resultaat;
	}
	
	public Verzameling<E> clone() {
		Verzameling<E> result = new Verzameling<E>();
		
		result.data = data.clone();
		
		return result;
	}
}
